package cn.net.xyan.blossom.security

import cn.net.xyan.blossom.kotlin.AllOpen
import cn.net.xyan.blossom.kotlin.logger
import cn.net.xyan.blossom.security.service.AuthService
import cn.net.xyan.blossom.security.service.BlossomAuthorizingRealm
import cn.net.xyan.blossom.security.service.DefaultAuthService
import org.apache.shiro.realm.AuthorizingRealm
import org.springframework.boot.autoconfigure.domain.EntityScan
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.ComponentScan
import org.springframework.context.annotation.Configuration
import org.springframework.data.jpa.repository.config.EnableJpaRepositories
import org.apache.shiro.web.mgt.DefaultWebSecurityManager
import org.apache.shiro.mgt.SecurityManager
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
import java.util.LinkedHashMap
import org.apache.shiro.spring.web.ShiroFilterFactoryBean




@AllOpen
@Configuration
@ComponentScan
@EnableJpaRepositories(basePackages = arrayOf("cn.net.xyan.blossom.security.dao"))
@EntityScan
class BlossomSecurityConfiguration{

    @Bean
    @ConditionalOnMissingBean
    fun shirFilter(securityManager: SecurityManager): ShiroFilterFactoryBean {
        logger.info("ShiroConfiguration.shirFilter()")

        val shiroFilterFactoryBean = ShiroFilterFactoryBean()
        shiroFilterFactoryBean.securityManager = securityManager

        //拦截器.
        val filterChainDefinitionMap = LinkedHashMap<String, String>()

        // 配置不会被拦截的链接 顺序判断
        filterChainDefinitionMap.put("/static/**", "anon")
        filterChainDefinitionMap.put("/public/**", "anon")
        filterChainDefinitionMap.put("/api/**", "anon")
        filterChainDefinitionMap.put("/webService/**", "anon")
        filterChainDefinitionMap.put("/VAADIN/**", "anon")
        filterChainDefinitionMap.put("/vaadinServlet/**", "anon")


        //配置退出 过滤器,其中的具体的退出代码Shiro已经替我们实现了
        filterChainDefinitionMap.put("/logout", "logout")

        //<!-- 过滤链定义，从上向下顺序执行，一般将/**放在最为下边 -->:这是一个坑呢，一不小心代码就不好使了;
        //<!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问-->
        filterChainDefinitionMap.put("/**", "authc")

        // 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
        shiroFilterFactoryBean.loginUrl = "/login"

        // 登录成功后要跳转的链接
        shiroFilterFactoryBean.successUrl = "/"

        //未授权界面;
        shiroFilterFactoryBean.unauthorizedUrl = "/403"
        shiroFilterFactoryBean.filterChainDefinitionMap = filterChainDefinitionMap
        return shiroFilterFactoryBean
    }

    @Bean
    @ConditionalOnMissingBean
    fun defaultShiroRealm(): AuthorizingRealm{
        return BlossomAuthorizingRealm()
    }

    @Bean
    @ConditionalOnMissingBean
    fun securityManager(realm:AuthorizingRealm): SecurityManager {
        val securityManager = DefaultWebSecurityManager()
        securityManager.setRealm(realm)
        return securityManager
    }

    @Bean
    @ConditionalOnMissingBean
    fun authService():AuthService{
        return DefaultAuthService()
    }
}